package cn.com.ejiakanghu.web;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.com.ejiakanghu.core.utils.RespUtil;
import cn.com.ejiakanghu.core.vo.BaseResult;
import cn.com.ejiakanghu.core.vo.R;
import cn.com.ejiakanghu.dto.UserInfo;
import cn.com.ejiakanghu.dto.UserRoleData;
import cn.com.ejiakanghu.dto.WxLoginInfo;
import cn.com.ejiakanghu.service.UserManager;
import cn.com.ejiakanghu.service.UserTokenManager;
import cn.com.ejiakanghu.web.alimini.AliAuthLoginUtil;
import com.alipay.api.AlipayApiException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.util.*;
import org.linlinjava.litemall.db.dao.AgedmallVipLevelMapper;
import org.linlinjava.litemall.db.domain.AgedmallAgent;
import org.linlinjava.litemall.db.domain.AgedmallVipLevel;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.service.AgedmallAgentService;
import org.linlinjava.litemall.db.service.AgedmallUserInfoService;
import org.linlinjava.litemall.db.service.CouponAssignService;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 鉴权服务
 */
@RestController
@RequestMapping("/ali/auth")
@Validated
public class AliAuthController {
    private Logger logger = LoggerFactory.getLogger(AliAuthController.class);

    @Autowired
    private LitemallUserService userService;

    @Autowired
    private UserManager userManager;

    @Autowired
    private AgedmallUserInfoService agedmallUserInfoService;

    @Resource
    private AgedmallVipLevelMapper agedmallVipLevelMapper;

    /**
     * @api {post} /ali/auth/loginByAli 支付宝登录
     * @apiGroup 鉴权服务
     * @apiVersion 0.1.0
     * @apiDescription 用户授权支付宝手机号登录
     * @apiSuccess {Object} Object
     * @apiSuccessExample {json} Success-Response:
     * { "msg": "成功", "code":0, "data": {} }
     */
    @PostMapping("/loginByAli")
    public BaseResult loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {
        String code = wxLoginInfo.getCode();
        UserInfo userInfo = wxLoginInfo.getUserInfo();
        if (code == null || userInfo == null) {
            return RespUtil.badArgument();
        }

        String openId = null;

        String encryptedData = wxLoginInfo.getData();
        if (StringUtils.isBlank(encryptedData)) {
            return RespUtil.fail();
        }
        String phone = aliAuthPhoneLogin(encryptedData);
        if (StringUtils.isBlank(phone)) {
            return RespUtil.fail();
        }
        R aliRst = aliMobileLogin(code, phone);
        openId = aliRst.get("token").toString();
        String mobile = phone;

        LitemallUser user = userService.queryByOid(openId);
        if (user == null) {
            user = new LitemallUser();
            user.setUsername(openId);
            user.setPassword(openId);
            user.setWeixinOpenid(openId);
            user.setAvatar(userInfo.getAvatarUrl());
            user.setNickname(userInfo.getNickName());
            user.setGender(userInfo.getGender());
            user.setUserLevel((byte) 0);
            user.setStatus((byte) 0);
            user.setLastLoginTime(LocalDateTime.now());
            user.setLastLoginIp(IpUtil.getIpAddr(request));
            user.setSessionKey("");
            user.setMobile(mobile);

            userService.add(user);
            agedmallUserInfoService.add(user.getId());

            // 新用户发送注册优惠券
//            couponAssignService.assignForRegister(user.getId());
        } else {
            user.setLastLoginTime(LocalDateTime.now());
            user.setLastLoginIp(IpUtil.getIpAddr(request));
            user.setSessionKey("");
            if (userService.updateById(user) == 0) {
                return RespUtil.updatedDataFailed();
            }
        }

        String token = UserTokenManager.generateToken(user.getId());
        UserRoleData roleData = userManager.getUserRoles(user.getId());
        userInfo.setRoles(roleData.getRoles());
        AgedmallVipLevel vipLevel = agedmallVipLevelMapper.selectByPrimaryKey(user.getUserLevel().intValue());
        userInfo.setVipLevel(vipLevel!=null?vipLevel.getVipLevel():0);

        // token
        Map<Object, Object> result = new HashMap<Object, Object>();
        result.put("token", token);
        result.put("userInfo", userInfo);
        return RespUtil.success(result);
    }

    public String aliAuthPhoneLogin(String res) {
        String data = null;
        try {
            data = AliAuthLoginUtil.decryptStr(res);
        } catch (Exception e) {
            e.printStackTrace();
        }

        logger.debug("aliGetPhoneData={}",data);
        Map<String,Object> dataMap = JacksonUtil.gson.fromJson(data,Map.class);
        if(dataMap == null) {
            logger.error("ali getphone data null");
            return null;
        }

        Object phoneObj = dataMap.get("mobile");
        if(phoneObj == null) {
            logger.error("ali getphone mobile null");
            return null;
        }
        String phone = phoneObj.toString();
        return phone;
    }

    /**
     * 支付宝手机号登录处理
     * @param code
     * @param mobile
     * @return
     */
    private R aliMobileLogin(String code, String mobile){
        Map<String,Object> aliUserInfoMap = null;
        String aliUid = "";
        R result = R.ok();
        try {
            aliUserInfoMap = AliAuthLoginUtil.loginAuthGetAccessToken(code);
            if(aliUserInfoMap == null) {
                logger.error("login fail ali phone={},authCode={}",new Object[]{mobile,code});
                return R.error(1,"登录失败");
            }
            aliUid = aliUserInfoMap.get("aliUid").toString();
            result.put("token",aliUid);
            result.putAll(aliUserInfoMap);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            logger.error("ali_login_exception {},{}",e.getErrMsg(),e.getErrCode());
            String desc = e.getErrMsg()+"("+e.getErrCode()+")";
            return R.error(1,desc);
        }
        if(org.apache.commons.lang3.StringUtils.isBlank(aliUid)) {
            return R.error(2,"登录失败");
        }

        return result;
    }

}
